<template>
  <div class="min-h-screen py-8 px-4 sm:px-6 lg:px-8">
    <div class="max-w-7xl mx-auto">
      <!-- 页面标题 -->
      <div class="text-center mb-12">
        <h1 class="text-4xl font-bold mb-4 tech-text">HTML 拖放 API</h1>
        <p class="text-gray-300 text-lg">
          原生拖放功能，实现元素的拖拽、排序和文件上传
        </p>
      </div>

      <!-- 浏览器支持提示 -->
      <div v-if="!isSupported" class="tech-card mb-8 border-yellow-600">
        <div class="flex items-center mb-4">
          <i class="i-carbon-warning text-yellow-500 text-xl mr-3"></i>
          <h3 class="text-xl font-semibold text-yellow-500">浏览器支持提示</h3>
        </div>
        <p class="text-gray-300">
          您的浏览器不支持 HTML5 拖放 API。此功能需要现代浏览器支持。
        </p>
      </div>

      <!-- 示例1: 基础拖放 -->
      <div class="tech-card mb-8">
        <h2 class="text-2xl font-semibold mb-6 text-white">基础拖放</h2>
        <p class="text-gray-300 mb-6">拖动下方的卡片到目标区域</p>
        
        <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
          <!-- 可拖动元素 -->
          <div class="space-y-4">
            <h3 class="text-lg font-semibold text-white mb-3">可拖动元素</h3>
            <div
              v-for="item in basicItems"
              :key="item.id"
              :draggable="true"
              @dragstart="handleDragStart($event, item)"
              @dragend="handleDragEnd"
              class="bg-gradient-to-r from-tech-accent to-tech-secondary p-4 rounded-lg cursor-move hover:scale-105 transition-transform"
              :class="{ 'opacity-50': draggedItem?.id === item.id }"
            >
              <div class="flex items-center">
                <i :class="item.icon" class="text-2xl mr-3 text-white"></i>
                <div>
                  <div class="text-white font-semibold">{{ item.title }}</div>
                  <div class="text-gray-200 text-sm">{{ item.description }}</div>
                </div>
              </div>
            </div>
          </div>

          <!-- 放置区域 -->
          <div>
            <h3 class="text-lg font-semibold text-white mb-3">放置区域</h3>
            <div
              @dragover.prevent="handleDragOver"
              @dragleave="handleDragLeave"
              @drop="handleDrop($event, 'basic')"
              class="min-h-[300px] border-2 border-dashed rounded-lg p-4 transition-all"
              :class="isDragOver ? 'border-tech-accent bg-tech-accent/10' : 'border-gray-600 bg-gray-800/50'"
            >
              <div v-if="droppedBasicItems.length === 0" class="h-full flex flex-col items-center justify-center text-gray-400">
                <i class="i-carbon-drag-vertical text-4xl mb-3"></i>
                <p>将元素拖放到这里</p>
              </div>
              <div v-else class="space-y-3">
                <div
                  v-for="item in droppedBasicItems"
                  :key="item.id"
                  class="bg-gray-700 p-3 rounded-lg flex items-center justify-between"
                >
                  <div class="flex items-center">
                    <i :class="item.icon" class="text-xl mr-3 text-tech-accent"></i>
                    <span class="text-white">{{ item.title }}</span>
                  </div>
                  <button
                    @click="removeBasicItem(item.id)"
                    class="text-red-400 hover:text-red-300"
                  >
                    <i class="i-carbon-close"></i>
                  </button>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 示例2: 列表排序 -->
      <div class="tech-card mb-8">
        <h2 class="text-2xl font-semibold mb-6 text-white">列表拖拽排序</h2>
        <p class="text-gray-300 mb-6">拖动下方的任务卡片来重新排序</p>
        
        <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
          <div
            v-for="list in taskLists"
            :key="list.id"
            class="bg-gray-800 rounded-lg p-4"
          >
            <h3 class="text-lg font-semibold text-white mb-4 flex items-center">
              <i :class="list.icon" class="mr-2 text-tech-accent"></i>
              {{ list.title }}
              <span class="ml-auto text-sm text-gray-400">{{ list.tasks.length }} 项</span>
            </h3>
            
            <div
              @dragover.prevent="handleListDragOver($event, list.id)"
              @drop="handleListDrop($event, list.id)"
              class="space-y-2 min-h-[200px]"
            >
              <div
                v-for="(task, index) in list.tasks"
                :key="task.id"
                :draggable="true"
                @dragstart="handleTaskDragStart($event, task, list.id, index)"
                @dragend="handleDragEnd"
                class="bg-gray-700 p-3 rounded-lg cursor-move hover:bg-gray-600 transition-colors"
                :class="{ 'opacity-50': draggedTask?.id === task.id }"
              >
                <div class="flex items-center justify-between">
                  <div class="flex items-center flex-1">
                    <i class="i-carbon-drag-vertical text-gray-400 mr-2"></i>
                    <div>
                      <div class="text-white font-medium">{{ task.title }}</div>
                      <div class="text-gray-400 text-sm">{{ task.description }}</div>
                    </div>
                  </div>
                  <span
                    class="px-2 py-1 rounded text-xs"
                    :class="getPriorityClass(task.priority)"
                  >
                    {{ task.priority }}
                  </span>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 示例3: 文件拖放上传 -->
      <div class="tech-card mb-8">
        <h2 class="text-2xl font-semibold mb-6 text-white">文件拖放上传</h2>
        <p class="text-gray-300 mb-6">拖放文件到下方区域进行上传</p>
        
        <div
          @dragover.prevent="handleFileDragOver"
          @dragleave="handleFileDragLeave"
          @drop="handleFileDrop"
          class="border-2 border-dashed rounded-lg p-8 transition-all"
          :class="isFileDragOver ? 'border-tech-accent bg-tech-accent/10' : 'border-gray-600 bg-gray-800/50'"
        >
          <div class="text-center">
            <i class="i-carbon-cloud-upload text-6xl text-tech-accent mb-4 block mx-auto"></i>
            <p class="text-white text-lg mb-2">拖放文件到这里</p>
            <p class="text-gray-400 text-sm mb-4">或者点击选择文件</p>
            <input
              ref="fileInputRef"
              type="file"
              multiple
              @change="handleFileSelect"
              class="hidden"
            >
            <button
              @click="fileInputRef?.click()"
              class="tech-button"
            >
              <i class="i-carbon-document-add mr-2"></i>
              选择文件
            </button>
          </div>
        </div>

        <!-- 上传文件列表 -->
        <div v-if="uploadedFiles.length > 0" class="mt-6 space-y-3">
          <h3 class="text-lg font-semibold text-white">已上传文件 ({{ uploadedFiles.length }})</h3>
          <div
            v-for="file in uploadedFiles"
            :key="file.id"
            class="bg-gray-800 rounded-lg p-4 flex items-center justify-between"
          >
            <div class="flex items-center flex-1">
              <i
                :class="getFileIcon(file.type)"
                class="text-2xl mr-4 text-tech-accent"
              ></i>
              <div class="flex-1">
                <div class="text-white font-medium">{{ file.name }}</div>
                <div class="text-gray-400 text-sm">
                  {{ formatFileSize(file.size) }} • {{ file.type || '未知类型' }}
                </div>
                <!-- 预览图片 -->
                <img
                  v-if="file.preview && file.type.startsWith('image/')"
                  :src="file.preview"
                  class="mt-2 max-w-xs max-h-32 rounded"
                  :alt="file.name"
                >
              </div>
            </div>
            <button
              @click="removeFile(file.id)"
              class="text-red-400 hover:text-red-300 ml-4"
            >
              <i class="i-carbon-trash-can text-xl"></i>
            </button>
          </div>
          <button
            @click="clearAllFiles"
            class="bg-red-600 hover:bg-red-700 text-white px-4 py-2 rounded-lg transition-colors"
          >
            <i class="i-carbon-clean mr-2"></i>
            清空所有文件
          </button>
        </div>
      </div>

      <!-- 示例4: 画板拖放 -->
      <div class="tech-card mb-8">
        <h2 class="text-2xl font-semibold mb-6 text-white">拖放画板</h2>
        <p class="text-gray-300 mb-6">拖动元素到画板上自由放置</p>
        
        <div class="grid grid-cols-1 lg:grid-cols-4 gap-6">
          <!-- 元素库 -->
          <div class="lg:col-span-1 space-y-3">
            <h3 class="text-lg font-semibold text-white mb-3">元素库</h3>
            <div
              v-for="shape in shapes"
              :key="shape.id"
              :draggable="true"
              @dragstart="handleShapeDragStart($event, shape)"
              class="bg-gray-700 p-3 rounded-lg cursor-move hover:bg-gray-600 transition-colors flex items-center"
            >
              <div
                class="w-8 h-8 mr-3 rounded flex items-center justify-center"
                :style="{ backgroundColor: shape.color }"
              >
                <i :class="shape.icon" class="text-white"></i>
              </div>
              <span class="text-white">{{ shape.name }}</span>
            </div>
          </div>

          <!-- 画板 -->
          <div class="lg:col-span-3">
            <div class="flex justify-between items-center mb-3">
              <h3 class="text-lg font-semibold text-white">画板</h3>
              <button
                @click="clearCanvas"
                class="bg-red-600 hover:bg-red-700 text-white px-3 py-1 rounded text-sm transition-colors"
              >
                <i class="i-carbon-clean mr-1"></i>
                清空
              </button>
            </div>
            <div
              ref="canvasRef"
              @dragover.prevent="handleCanvasDragOver"
              @drop="handleCanvasDrop"
              class="relative bg-gray-800 rounded-lg overflow-hidden"
              style="height: 500px;"
            >
              <div
                v-for="item in canvasItems"
                :key="item.id"
                :draggable="true"
                @dragstart="handleCanvasItemDragStart($event, item)"
                @dragend="handleDragEnd"
                class="absolute cursor-move"
                :style="{
                  left: item.x + 'px',
                  top: item.y + 'px',
                  opacity: draggedCanvasItem?.id === item.id ? 0.5 : 1
                }"
              >
                <div
                  class="w-16 h-16 rounded-lg flex items-center justify-center shadow-lg hover:scale-110 transition-transform"
                  :style="{ backgroundColor: item.color }"
                >
                  <i :class="item.icon" class="text-white text-2xl"></i>
                </div>
              </div>
              
              <div v-if="canvasItems.length === 0" class="absolute inset-0 flex items-center justify-center text-gray-500">
                <div class="text-center">
                  <i class="i-carbon-add text-4xl mb-2"></i>
                  <p>从左侧拖动元素到这里</p>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- API 信息 -->
      <div class="tech-card">
        <h3 class="text-xl font-semibold mb-4 text-white">API 信息</h3>
        <div class="space-y-4 text-gray-300">
          <div>
            <h4 class="font-semibold text-tech-accent mb-2">浏览器支持</h4>
            <p>所有现代浏览器都支持 HTML5 拖放 API</p>
          </div>
          <div>
            <h4 class="font-semibold text-tech-accent mb-2">拖动事件</h4>
            <ul class="list-disc list-inside space-y-1">
              <li><code class="bg-gray-800 px-2 py-1 rounded">dragstart</code> - 开始拖动元素</li>
              <li><code class="bg-gray-800 px-2 py-1 rounded">drag</code> - 正在拖动元素</li>
              <li><code class="bg-gray-800 px-2 py-1 rounded">dragend</code> - 结束拖动元素</li>
            </ul>
          </div>
          <div>
            <h4 class="font-semibold text-tech-accent mb-2">放置事件</h4>
            <ul class="list-disc list-inside space-y-1">
              <li><code class="bg-gray-800 px-2 py-1 rounded">dragenter</code> - 拖动元素进入目标</li>
              <li><code class="bg-gray-800 px-2 py-1 rounded">dragover</code> - 拖动元素在目标上方</li>
              <li><code class="bg-gray-800 px-2 py-1 rounded">dragleave</code> - 拖动元素离开目标</li>
              <li><code class="bg-gray-800 px-2 py-1 rounded">drop</code> - 在目标上放置元素</li>
            </ul>
          </div>
          <div>
            <h4 class="font-semibold text-tech-accent mb-2">DataTransfer 对象</h4>
            <ul class="list-disc list-inside space-y-1">
              <li><code class="bg-gray-800 px-2 py-1 rounded">setData()</code> - 设置拖动数据</li>
              <li><code class="bg-gray-800 px-2 py-1 rounded">getData()</code> - 获取拖动数据</li>
              <li><code class="bg-gray-800 px-2 py-1 rounded">files</code> - 获取拖动的文件</li>
              <li><code class="bg-gray-800 px-2 py-1 rounded">effectAllowed</code> - 允许的拖动效果</li>
              <li><code class="bg-gray-800 px-2 py-1 rounded">dropEffect</code> - 放置效果</li>
            </ul>
          </div>
          <div>
            <h4 class="font-semibold text-tech-accent mb-2">使用场景</h4>
            <ul class="list-disc list-inside space-y-1">
              <li>拖拽排序和重新组织列表</li>
              <li>文件上传界面</li>
              <li>看板和任务管理系统</li>
              <li>可视化编辑器和设计工具</li>
              <li>图片库和相册管理</li>
            </ul>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'

// 类型定义
interface BasicItem {
  id: string
  title: string
  description: string
  icon: string
}

interface Task {
  id: string
  title: string
  description: string
  priority: 'high' | 'medium' | 'low'
}

interface TaskList {
  id: string
  title: string
  icon: string
  tasks: Task[]
}

interface UploadedFile {
  id: string
  name: string
  size: number
  type: string
  preview?: string
}

interface Shape {
  id: string
  name: string
  icon: string
  color: string
}

interface CanvasItem {
  id: string
  icon: string
  color: string
  x: number
  y: number
}

// 响应式状态
const isSupported = ref('draggable' in document.createElement('div'))

// 基础拖放
const basicItems = ref<BasicItem[]>([
  { id: '1', title: 'Vue 3', description: '渐进式 JavaScript 框架', icon: 'i-carbon-logo-vue' },
  { id: '2', title: 'React', description: '用于构建用户界面的库', icon: 'i-carbon-logo-react' },
  { id: '3', title: 'Angular', description: '完整的前端框架', icon: 'i-carbon-application' },
  { id: '4', title: 'TypeScript', description: '类型安全的 JavaScript', icon: 'i-carbon-code' }
])

const fileInputRef = ref<HTMLInputElement>()
const droppedBasicItems = ref<BasicItem[]>([])
const draggedItem = ref<BasicItem | null>(null)
const isDragOver = ref(false)

// 列表排序
const taskLists = ref<TaskList[]>([
  {
    id: 'todo',
    title: '待办事项',
    icon: 'i-carbon-task',
    tasks: [
      { id: 't1', title: '完成项目文档', description: '编写 API 文档', priority: 'high' },
      { id: 't2', title: '代码审查', description: '审查 PR #123', priority: 'medium' },
      { id: 't3', title: '更新依赖', description: '升级到最新版本', priority: 'low' }
    ]
  },
  {
    id: 'progress',
    title: '进行中',
    icon: 'i-carbon-in-progress',
    tasks: [
      { id: 't4', title: '开发新功能', description: '实现拖放 API', priority: 'high' },
      { id: 't5', title: '修复 Bug', description: '解决样式问题', priority: 'medium' }
    ]
  }
])

const draggedTask = ref<Task | null>(null)
const draggedTaskListId = ref<string | null>(null)

// 文件上传
const uploadedFiles = ref<UploadedFile[]>([])
const isFileDragOver = ref(false)

// 画板
const shapes = ref<Shape[]>([
  { id: 's1', name: '圆形', icon: 'i-carbon-radio-button', color: '#3b82f6' },
  { id: 's2', name: '方形', icon: 'i-carbon-checkbox', color: '#10b981' },
  { id: 's3', name: '星形', icon: 'i-carbon-star-filled', color: '#f59e0b' },
  { id: 's4', name: '心形', icon: 'i-carbon-favorite-filled', color: '#ef4444' },
  { id: 's5', name: '图钉', icon: 'i-carbon-pin-filled', color: '#8b5cf6' }
])

const canvasItems = ref<CanvasItem[]>([])
const draggedCanvasItem = ref<CanvasItem | null>(null)
const canvasRef = ref<HTMLElement | null>(null)

// 基础拖放处理
const handleDragStart = (event: DragEvent, item: BasicItem) => {
  draggedItem.value = item
  if (event.dataTransfer) {
    event.dataTransfer.effectAllowed = 'move'
    event.dataTransfer.setData('application/json', JSON.stringify(item))
  }
}

const handleDragEnd = () => {
  draggedItem.value = null
  draggedTask.value = null
  draggedCanvasItem.value = null
}

const handleDragOver = () => {
  isDragOver.value = true
}

const handleDragLeave = () => {
  isDragOver.value = false
}

const handleDrop = (event: DragEvent, type: string) => {
  event.preventDefault()
  isDragOver.value = false
  
  if (type === 'basic' && event.dataTransfer) {
    try {
      const data = event.dataTransfer.getData('application/json')
      const item: BasicItem = JSON.parse(data)
      
      // 检查是否已经存在
      if (!droppedBasicItems.value.find(i => i.id === item.id)) {
        droppedBasicItems.value.push(item)
      }
    } catch (err) {
      console.error('解析拖放数据失败:', err)
    }
  }
}

const removeBasicItem = (id: string) => {
  droppedBasicItems.value = droppedBasicItems.value.filter(item => item.id !== id)
}

// 列表排序处理
const handleTaskDragStart = (event: DragEvent, task: Task, listId: string, _index: number) => {
  draggedTask.value = task
  draggedTaskListId.value = listId
  if (event.dataTransfer) {
    event.dataTransfer.effectAllowed = 'move'
    event.dataTransfer.setData('application/json', JSON.stringify({ task, listId }))
  }
}

const handleListDragOver = (event: DragEvent, _listId: string) => {
  event.preventDefault()
}

const handleListDrop = (event: DragEvent, targetListId: string) => {
  event.preventDefault()
  
  if (!event.dataTransfer) return
  
  try {
    const data = event.dataTransfer.getData('application/json')
    const { task, listId: sourceListId } = JSON.parse(data)
    
    // 从源列表移除
    const sourceList = taskLists.value.find(list => list.id === sourceListId)
    if (sourceList) {
      sourceList.tasks = sourceList.tasks.filter(t => t.id !== task.id)
    }
    
    // 添加到目标列表
    const targetList = taskLists.value.find(list => list.id === targetListId)
    if (targetList) {
      targetList.tasks.push(task)
    }
  } catch (err) {
    console.error('解析任务数据失败:', err)
  }
}

const getPriorityClass = (priority: string) => {
  const classes = {
    high: 'bg-red-600 text-white',
    medium: 'bg-yellow-600 text-white',
    low: 'bg-green-600 text-white'
  }
  return classes[priority as keyof typeof classes] || 'bg-gray-600 text-white'
}

// 文件上传处理
const handleFileDragOver = () => {
  isFileDragOver.value = true
}

const handleFileDragLeave = () => {
  isFileDragOver.value = false
}

const handleFileDrop = (event: DragEvent) => {
  event.preventDefault()
  isFileDragOver.value = false
  
  if (event.dataTransfer?.files) {
    processFiles(event.dataTransfer.files)
  }
}

const handleFileSelect = (event: Event) => {
  const input = event.target as HTMLInputElement
  if (input.files) {
    processFiles(input.files)
  }
}

const processFiles = (files: FileList) => {
  Array.from(files).forEach(file => {
    const uploadedFile: UploadedFile = {
      id: `file-${Date.now()}-${Math.random()}`,
      name: file.name,
      size: file.size,
      type: file.type
    }
    
    // 为图片创建预览
    if (file.type.startsWith('image/')) {
      const reader = new FileReader()
      reader.onload = (e) => {
        uploadedFile.preview = e.target?.result as string
      }
      reader.readAsDataURL(file)
    }
    
    uploadedFiles.value.push(uploadedFile)
  })
}

const removeFile = (id: string) => {
  uploadedFiles.value = uploadedFiles.value.filter(file => file.id !== id)
}

const clearAllFiles = () => {
  uploadedFiles.value = []
}

const formatFileSize = (bytes: number): string => {
  if (bytes === 0) return '0 B'
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return Math.round(bytes / Math.pow(k, i) * 100) / 100 + ' ' + sizes[i]
}

const getFileIcon = (type: string): string => {
  if (type.startsWith('image/')) return 'i-carbon-image'
  if (type.startsWith('video/')) return 'i-carbon-video'
  if (type.startsWith('audio/')) return 'i-carbon-music'
  if (type.includes('pdf')) return 'i-carbon-document-pdf'
  if (type.includes('zip') || type.includes('rar')) return 'i-carbon-zip'
  return 'i-carbon-document'
}

// 画板处理
const handleShapeDragStart = (event: DragEvent, shape: Shape) => {
  if (event.dataTransfer) {
    event.dataTransfer.effectAllowed = 'copy'
    event.dataTransfer.setData('application/json', JSON.stringify(shape))
  }
}

const handleCanvasDragOver = (event: DragEvent) => {
  event.preventDefault()
}

const handleCanvasDrop = (event: DragEvent) => {
  event.preventDefault()
  
  if (!event.dataTransfer || !canvasRef.value) return
  
  const rect = canvasRef.value.getBoundingClientRect()
  const x = event.clientX - rect.left - 32 // 减去元素宽度的一半
  const y = event.clientY - rect.top - 32 // 减去元素高度的一半
  
  try {
    // 尝试解析形状数据（从元素库拖入）
    const data = event.dataTransfer.getData('application/json')
    if (data) {
      const shape: Shape = JSON.parse(data)
      
      const newItem: CanvasItem = {
        id: `item-${Date.now()}-${Math.random()}`,
        icon: shape.icon,
        color: shape.color,
        x: Math.max(0, Math.min(x, rect.width - 64)),
        y: Math.max(0, Math.min(y, rect.height - 64))
      }
      
      canvasItems.value.push(newItem)
    }
  } catch (err) {
    // 可能是移动现有元素
    if (draggedCanvasItem.value) {
      const item = canvasItems.value.find(i => i.id === draggedCanvasItem.value!.id)
      if (item) {
        item.x = Math.max(0, Math.min(x, rect.width - 64))
        item.y = Math.max(0, Math.min(y, rect.height - 64))
      }
    }
  }
}

const handleCanvasItemDragStart = (event: DragEvent, item: CanvasItem) => {
  draggedCanvasItem.value = item
  if (event.dataTransfer) {
    event.dataTransfer.effectAllowed = 'move'
  }
}

const clearCanvas = () => {
  canvasItems.value = []
}
</script>

